#ifndef THINK_THINK_CONSOLE_COMMAND_H
#define THINK_THINK_CONSOLE_COMMAND_H

static char* think_console_command =
	"\n"
	"// +----------------------------------------------------------------------\n"
	"// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n"
	"// +----------------------------------------------------------------------\n"
	"// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n"
	"// +----------------------------------------------------------------------\n"
	"// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n"
	"// +----------------------------------------------------------------------\n"
	"// | Author: yunwuxin <448901948@qq.com>\n"
	"// +----------------------------------------------------------------------\n"
	"\n"
	"namespace think\\console;\n"
	"\n"
	"use think\\Console;\n"
	"use think\\console\\input\\Argument;\n"
	"use think\\console\\input\\Definition;\n"
	"use think\\console\\input\\Option;\n"
	"\n"
	"class Command\n"
	"{\n"
	"\n"
	"    /** @var  Console */\n"
	"    private $console;\n"
	"    private $name;\n"
	"    private $aliases = [];\n"
	"    private $definition;\n"
	"    private $help;\n"
	"    private $description;\n"
	"    private $ignoreValidationErrors          = false;\n"
	"    private $consoleDefinitionMerged         = false;\n"
	"    private $consoleDefinitionMergedWithArgs = false;\n"
	"    private $code;\n"
	"    private $synopsis = [];\n"
	"    private $usages   = [];\n"
	"\n"
	"    /** @var  Input */\n"
	"    protected $input;\n"
	"\n"
	"    /** @var  Output */\n"
	"    protected $output;\n"
	"\n"
	"    /**\n"
	"     * 构造方法\n"
	"     * @param string|null $name 命令名称,如果没有设置则比如在 configure() 里设置\n"
	"     * @throws \\LogicException\n"
	"     * @api\n"
	"     */\n"
	"    public function __construct($name = null)\n"
	"    {\n"
	"        $this->definition = new Definition();\n"
	"\n"
	"        if (null !== $name) {\n"
	"            $this->setName($name);\n"
	"        }\n"
	"\n"
	"        $this->configure();\n"
	"\n"
	"        if (!$this->name) {\n"
	"            throw new \\LogicException(sprintf(\'The command defined in \"%s\" cannot have an empty name.\', get_class($this)));\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 忽略验证错误\n"
	"     */\n"
	"    public function ignoreValidationErrors()\n"
	"    {\n"
	"        $this->ignoreValidationErrors = true;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置控制台\n"
	"     * @param Console $console\n"
	"     */\n"
	"    public function setConsole(Console $console = null)\n"
	"    {\n"
	"        $this->console = $console;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取控制台\n"
	"     * @return Console\n"
	"     * @api\n"
	"     */\n"
	"    public function getConsole()\n"
	"    {\n"
	"        return $this->console;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 是否有效\n"
	"     * @return bool\n"
	"     */\n"
	"    public function isEnabled()\n"
	"    {\n"
	"        return true;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 配置指令\n"
	"     */\n"
	"    protected function configure()\n"
	"    {\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 执行指令\n"
	"     * @param Input  $input\n"
	"     * @param Output $output\n"
	"     * @return null|int\n"
	"     * @throws \\LogicException\n"
	"     * @see setCode()\n"
	"     */\n"
	"    protected function execute(Input $input, Output $output)\n"
	"    {\n"
	"        throw new \\LogicException(\'You must override the execute() method in the concrete command class.\');\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 用户验证\n"
	"     * @param Input  $input\n"
	"     * @param Output $output\n"
	"     */\n"
	"    protected function interact(Input $input, Output $output)\n"
	"    {\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 初始化\n"
	"     * @param Input  $input  An InputInterface instance\n"
	"     * @param Output $output An OutputInterface instance\n"
	"     */\n"
	"    protected function initialize(Input $input, Output $output)\n"
	"    {\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 执行\n"
	"     * @param Input  $input\n"
	"     * @param Output $output\n"
	"     * @return int\n"
	"     * @throws \\Exception\n"
	"     * @see setCode()\n"
	"     * @see execute()\n"
	"     */\n"
	"    public function run(Input $input, Output $output)\n"
	"    {\n"
	"        $this->input  = $input;\n"
	"        $this->output = $output;\n"
	"\n"
	"        $this->getSynopsis(true);\n"
	"        $this->getSynopsis(false);\n"
	"\n"
	"        $this->mergeConsoleDefinition();\n"
	"\n"
	"        try {\n"
	"            $input->bind($this->definition);\n"
	"        } catch (\\Exception $e) {\n"
	"            if (!$this->ignoreValidationErrors) {\n"
	"                throw $e;\n"
	"            }\n"
	"        }\n"
	"\n"
	"        $this->initialize($input, $output);\n"
	"\n"
	"        if ($input->isInteractive()) {\n"
	"            $this->interact($input, $output);\n"
	"        }\n"
	"\n"
	"        $input->validate();\n"
	"\n"
	"        if ($this->code) {\n"
	"            $statusCode = call_user_func($this->code, $input, $output);\n"
	"        } else {\n"
	"            $statusCode = $this->execute($input, $output);\n"
	"        }\n"
	"\n"
	"        return is_numeric($statusCode) ? (int) $statusCode : 0;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置执行代码\n"
	"     * @param callable $code callable(InputInterface $input, OutputInterface $output)\n"
	"     * @return Command\n"
	"     * @throws \\InvalidArgumentException\n"
	"     * @see execute()\n"
	"     */\n"
	"    public function setCode(callable $code)\n"
	"    {\n"
	"        if (!is_callable($code)) {\n"
	"            throw new \\InvalidArgumentException(\'Invalid callable provided to Command::setCode.\');\n"
	"        }\n"
	"\n"
	"        if (PHP_VERSION_ID >= 50400 && $code instanceof \\Closure) {\n"
	"            $r = new \\ReflectionFunction($code);\n"
	"            if (null === $r->getClosureThis()) {\n"
	"                $code = \\Closure::bind($code, $this);\n"
	"            }\n"
	"        }\n"
	"\n"
	"        $this->code = $code;\n"
	"\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 合并参数定义\n"
	"     * @param bool $mergeArgs\n"
	"     */\n"
	"    public function mergeConsoleDefinition($mergeArgs = true)\n"
	"    {\n"
	"        if (null === $this->console\n"
	"            || (true === $this->consoleDefinitionMerged\n"
	"                && ($this->consoleDefinitionMergedWithArgs || !$mergeArgs))\n"
	"        ) {\n"
	"            return;\n"
	"        }\n"
	"\n"
	"        if ($mergeArgs) {\n"
	"            $currentArguments = $this->definition->getArguments();\n"
	"            $this->definition->setArguments($this->console->getDefinition()->getArguments());\n"
	"            $this->definition->addArguments($currentArguments);\n"
	"        }\n"
	"\n"
	"        $this->definition->addOptions($this->console->getDefinition()->getOptions());\n"
	"\n"
	"        $this->consoleDefinitionMerged = true;\n"
	"        if ($mergeArgs) {\n"
	"            $this->consoleDefinitionMergedWithArgs = true;\n"
	"        }\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置参数定义\n"
	"     * @param array|Definition $definition\n"
	"     * @return Command\n"
	"     * @api\n"
	"     */\n"
	"    public function setDefinition($definition)\n"
	"    {\n"
	"        if ($definition instanceof Definition) {\n"
	"            $this->definition = $definition;\n"
	"        } else {\n"
	"            $this->definition->setDefinition($definition);\n"
	"        }\n"
	"\n"
	"        $this->consoleDefinitionMerged = false;\n"
	"\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取参数定义\n"
	"     * @return Definition\n"
	"     * @api\n"
	"     */\n"
	"    public function getDefinition()\n"
	"    {\n"
	"        return $this->definition;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取当前指令的参数定义\n"
	"     * @return Definition\n"
	"     */\n"
	"    public function getNativeDefinition()\n"
	"    {\n"
	"        return $this->getDefinition();\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 添加参数\n"
	"     * @param string $name        名称\n"
	"     * @param int    $mode        类型\n"
	"     * @param string $description 描述\n"
	"     * @param mixed  $default     默认值\n"
	"     * @return Command\n"
	"     */\n"
	"    public function addArgument($name, $mode = null, $description = \'\', $default = null)\n"
	"    {\n"
	"        $this->definition->addArgument(new Argument($name, $mode, $description, $default));\n"
	"\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 添加选项\n"
	"     * @param string $name        选项名称\n"
	"     * @param string $shortcut    别名\n"
	"     * @param int    $mode        类型\n"
	"     * @param string $description 描述\n"
	"     * @param mixed  $default     默认值\n"
	"     * @return Command\n"
	"     */\n"
	"    public function addOption($name, $shortcut = null, $mode = null, $description = \'\', $default = null)\n"
	"    {\n"
	"        $this->definition->addOption(new Option($name, $shortcut, $mode, $description, $default));\n"
	"\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置指令名称\n"
	"     * @param string $name\n"
	"     * @return Command\n"
	"     * @throws \\InvalidArgumentException\n"
	"     */\n"
	"    public function setName($name)\n"
	"    {\n"
	"        $this->validateName($name);\n"
	"\n"
	"        $this->name = $name;\n"
	"\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取指令名称\n"
	"     * @return string\n"
	"     */\n"
	"    public function getName()\n"
	"    {\n"
	"        return $this->name;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置描述\n"
	"     * @param string $description\n"
	"     * @return Command\n"
	"     */\n"
	"    public function setDescription($description)\n"
	"    {\n"
	"        $this->description = $description;\n"
	"\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     *  获取描述\n"
	"     * @return string\n"
	"     */\n"
	"    public function getDescription()\n"
	"    {\n"
	"        return $this->description;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置帮助信息\n"
	"     * @param string $help\n"
	"     * @return Command\n"
	"     */\n"
	"    public function setHelp($help)\n"
	"    {\n"
	"        $this->help = $help;\n"
	"\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取帮助信息\n"
	"     * @return string\n"
	"     */\n"
	"    public function getHelp()\n"
	"    {\n"
	"        return $this->help;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 描述信息\n"
	"     * @return string\n"
	"     */\n"
	"    public function getProcessedHelp()\n"
	"    {\n"
	"        $name = $this->name;\n"
	"\n"
	"        $placeholders = [\n"
	"            \'%command.name%\',\n"
	"            \'%command.full_name%\',\n"
	"        ];\n"
	"        $replacements = [\n"
	"            $name,\n"
	"            $_SERVER[\'PHP_SELF\'] . \' \' . $name,\n"
	"        ];\n"
	"\n"
	"        return str_replace($placeholders, $replacements, $this->getHelp());\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 设置别名\n"
	"     * @param string[] $aliases\n"
	"     * @return Command\n"
	"     * @throws \\InvalidArgumentException\n"
	"     */\n"
	"    public function setAliases($aliases)\n"
	"    {\n"
	"        if (!is_array($aliases) && !$aliases instanceof \\Traversable) {\n"
	"            throw new \\InvalidArgumentException(\'$aliases must be an array or an instance of \\Traversable\');\n"
	"        }\n"
	"\n"
	"        foreach ($aliases as $alias) {\n"
	"            $this->validateName($alias);\n"
	"        }\n"
	"\n"
	"        $this->aliases = $aliases;\n"
	"\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取别名\n"
	"     * @return array\n"
	"     */\n"
	"    public function getAliases()\n"
	"    {\n"
	"        return $this->aliases;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取简介\n"
	"     * @param bool $short 是否简单的\n"
	"     * @return string\n"
	"     */\n"
	"    public function getSynopsis($short = false)\n"
	"    {\n"
	"        $key = $short ? \'short\' : \'long\';\n"
	"\n"
	"        if (!isset($this->synopsis[$key])) {\n"
	"            $this->synopsis[$key] = trim(sprintf(\'%s %s\', $this->name, $this->definition->getSynopsis($short)));\n"
	"        }\n"
	"\n"
	"        return $this->synopsis[$key];\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 添加用法介绍\n"
	"     * @param string $usage\n"
	"     * @return $this\n"
	"     */\n"
	"    public function addUsage($usage)\n"
	"    {\n"
	"        if (0 !== strpos($usage, $this->name)) {\n"
	"            $usage = sprintf(\'%s %s\', $this->name, $usage);\n"
	"        }\n"
	"\n"
	"        $this->usages[] = $usage;\n"
	"\n"
	"        return $this;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 获取用法介绍\n"
	"     * @return array\n"
	"     */\n"
	"    public function getUsages()\n"
	"    {\n"
	"        return $this->usages;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 验证指令名称\n"
	"     * @param string $name\n"
	"     * @throws \\InvalidArgumentException\n"
	"     */\n"
	"    private function validateName($name)\n"
	"    {\n"
	"        if (!preg_match(\'/^[^\\:]++(\\:[^\\:]++)*$/\', $name)) {\n"
	"            throw new \\InvalidArgumentException(sprintf(\'Command name \"%s\" is invalid.\', $name));\n"
	"        }\n"
	"    }\n"
	"}\n"
	"\n"
;
#endif